home *** CD-ROM | disk | FTP | other *** search
Text File | 1995-11-15 | 15.7 KB | 635 lines | [TEXT/MPS ] |
- // Tumbler)event.c
- //
- // Event handling routines.
- //
- // Author: Nick Thompson & Pablo Fernicola, with thanks to the QuickDraw 3D team
- // Date: Monday, Janurary 20, 1992
- //
- // Copyright © 1992-95 Apple Computer, Inc., All Rights Reserved
- //
- // Modification History:
- // 12/2/94 nick
-
- //
- // Debugging Aids :
- //
- // Turn this flag on to see where the current hilite region is.
- //
- // #define _FLASH_HILITE_RGN_
- //
- //
-
- #include <Drag.h>
- #include "QD3D.h"
-
- #include "Tumbler_globals.h"
- #include "Tumbler_prototypes.h"
- #include "Tumbler_resources.h"
- #include "AppleEvents.h"
- #include "Events.h"
-
- #include "QD3DView.h"
- #include "QD3DDrawContext.h"
- #include "QD3DDrawContext.h"
- #include "QD3DPick.h"
- #include "QD3DTransform.h"
- #include "QD3DLight.h"
- #include "QD3DMath.h"
- #include "QD3DGeometry.h"
-
- #define SleepDuration 20 /* WaitNextEvent sleep constant */
-
- #include "Tumbler_event.h"
- #include "Tumbler_camera.h"
- #include "Tumbler_drag.h"
- #include "Tumbler_offscreen.h"
- #include "Tumbler_windows.h"
- #include "Tumbler_menus.h"
- #include "Tumbler_drag.h"
- #include "Tumbler_document.h"
- #include "Tumbler_cursor.h"
-
- #ifdef PODIUM_APP
- #include "Tumbler_Podium.h"
- #endif
-
- static void DoContentClick(WindowPtr theWindow, EventRecord *theEvent);
- static void DoBackgroundContentClick(WindowPtr theWindow, EventRecord *theEvent) ;
- static void DoMouseDown(EventRecord *theEvent);
- static void DoKey(char theChar);
- static void DoKeyDown(EventRecord *theEvent);
- static void DoActivate(EventRecord *theEvent);
- static void DoUpdate(EventRecord *theEvent);
- static void DoOSEvent(EventRecord *theEvent);
- static void DoHighLevelEvent(EventRecord *theEvent);
- static void DoEvent(EventRecord *theEvent);
- static void DoIdleHitTest(void);
- static void DoIdle(void);
-
-
-
-
-
- //-------------------------------------------------------------------------------------
- // DoContentClick handles mouseDown events in the content region of a document window.
- //
- // (1) If the mouseDown is on a draggable object (the document's hiliteRgn) and a
- // successful drag occurs, no further processing is necessary.
- //
- // (2) If the mouseDown is not on a draggable object and within the viewRect of the
- // TextEdit field, call TEClick to handle the mouseDown.
-
- static void DoContentClick( WindowPtr theWindow, EventRecord *theEvent)
-
- { short thePart;
- Point thePoint;
- ControlHandle theControl;
- DocumentPtr theDocument = GetDocumentFromWindow(theWindow);
- GrafPtr savedPort ;
-
- if( theWindow == nil )
- return ;
-
- GetPort( &savedPort) ;
- SetPort( theWindow ) ;
-
- thePoint = theEvent->where;
- GlobalToLocal(&thePoint);
-
- if( theDocument->documentGroup ) {
-
-
- // we can only do a drag if the option key is held down
-
- if (theEvent->modifiers & optionKey) {
- RgnHandle tempRgn = NewRgn(); // Nick this needs to be the BBox of the group
-
- RectRgn(tempRgn, &theWindow->portRect);
- DoDragObjects(theDocument, theEvent, tempRgn ) ;
-
- DisposeRgn(tempRgn);
- } else {
- Point oldMouse;
- Point newMouse;
- long mouseChanged = 0;
- long dx, dy, x, y, oldX, oldY;
- float width, height;
- float xRot, yRot;
-
- GetMouse(&newMouse); // get the mouse in local co-ordinates,
- // local to the current GrafPort
-
- oldX = newMouse.h;
- oldY = newMouse.v;
-
- width = theWindow->portRect.left - theWindow->portRect.right;
- height = theWindow->portRect.bottom - theWindow->portRect.top;
-
- while (WaitMouseUp()) {
-
- GetMouse(&newMouse); // get the mouse in local co-ordinates,
- // local to the current GrafPort
-
- dx = oldY - newMouse.v;
- dy = newMouse.h - oldX;
-
- if ((dx != 0) || (dy != 0)) {
- TQ3Matrix4x4 tempMatrix;
-
- xRot = ((float) dx * kQ3Pi) / width;
- yRot = ((float) dy * kQ3Pi) / height;
-
- if ((xRot != 0.0) || (yRot != 0.0)) {
- Q3Matrix4x4_SetRotate_XYZ(&tempMatrix, xRot, yRot, 0.0);
- Q3Matrix4x4_Multiply(&theDocument->modelRotation, &tempMatrix, &theDocument->modelRotation);
-
- mouseChanged = 1;
- DrawOffscreen(theDocument);
- }
- }
- oldX = newMouse.h; oldY = newMouse.v;
- }
-
- if( mouseChanged ) {
- theDocument->rotationDir.x = xRot;
- theDocument->rotationDir.y = yRot;
- DrawOffscreen(theDocument);
-
- DoDrawGrowIcon(theDocument->theWindow);
- }
- }
- }
-
- SetPort( savedPort ) ;
-
- }
-
-
- //
- // DoBackgroundContentClick handles mouseDown events in the content region of a document window
- // when the window is not frontmost. The following bullet items describe how this background
- // mouseDown event is handled:
- //
- // (1) If the mouseDown is not in a draggable object (not in the document's hiliteRgn) call
- // SelectWindow to bring the window to the front as usual.
- //
- // (2) If the mouseDown is in a draggable object and the mouse is released without
- // dragging, call SelectWindow when the mouse is released.
- //
- // (3) If the mouseDown is in a draggable object and a successful drag occurs, SelectWindow
- // should only be called if the drop occurred in the same window (the DoDragObjects function
- // calls SelectWindow in this case).
- //
-
- static void DoBackgroundContentClick(WindowPtr theWindow, EventRecord *theEvent)
- {
- short thePart;
- Point thePoint;
- ControlHandle theControl;
- DocumentPtr theDocument ;
- RgnHandle tempRgn = NewRgn(); // Nick will fix later, needs to be the bbox of the group
-
- if( theWindow == nil )
- return ;
-
- SetPort( theWindow );
- theDocument = GetDocumentFromWindow(theWindow);
-
- thePoint = theEvent->where;
- GlobalToLocal(&thePoint);
-
- RectRgn(tempRgn, &theWindow->portRect);
-
- if (PtInRgn(thePoint, tempRgn)) {
-
- if (! DoDragObjects(theDocument, theEvent, tempRgn)) {
- SelectWindow(theDocument->theWindow);
- }
-
- } else {
-
- SelectWindow(theDocument->theWindow);
-
- }
- DisposeRgn( tempRgn );
- }
-
-
- //
- // DoMouseDown is called to handle mouseDown events.
- //
-
- static void DoMouseDown(EventRecord *theEvent)
-
- { short thePart;
- WindowPtr theWindow;
- Rect dragRect;
- DocumentPtr theDocument;
-
-
- thePart = FindWindow(theEvent->where, &theWindow);
- switch(thePart) {
-
- case inMenuBar:
- PrepareMenus();
- DoMenuCommand(MenuSelect(theEvent->where));
- break;
-
- case inSysWindow:
- SystemClick(theEvent, theWindow);
- break;
- case inContent:
-
- if (theWindow == FrontWindow()) {
- #ifndef PODIUM_APP
- DoContentClick(theWindow, theEvent);
- #else
- Podium_DoContent( GetDocumentFromWindow(theWindow), theEvent ) ;
- #endif
- } else {
- #ifndef PODIUM_APP
- DoBackgroundContentClick(theWindow, theEvent);
- #else
- Podium_DoBackgroundContent( GetDocumentFromWindow(theWindow), theEvent ) ;
- #endif
- }
- break;
-
- case inDrag:
- if (theWindow != FrontWindow())
- SelectWindow(theWindow);
- dragRect = qd.screenBits.bounds;
- DragWindow(theWindow, theEvent->where, &dragRect);
- break;
-
- case inGrow:
-
- if ((theDocument = GetDocumentFromWindow(theWindow)) != nil) {
- GrowDocumentWindow(theWindow, theEvent->where);
- }
- break;
-
- case inGoAway:
- if ((theDocument = GetDocumentFromWindow(theWindow)) != nil)
- if (TrackGoAway(theWindow, theEvent->where)) {
- (void)CloseDocument(theDocument); // it's not important what the result is here
- }
- break;
- }
- }
-
-
- //
- // DoKey is called each time a character is typed on the keyboard to
- // be entered into a document window.
- //
-
- static void DoKey(char theChar)
-
- { WindowPtr theWindow;
- DocumentPtr theDocument;
-
- if ((theWindow = FrontWindow()) != nil) {
- if ((theDocument = GetDocumentFromWindow(theWindow)) != nil) {
- // what d'ya want to do here?
- }
- }
- }
-
-
- //
- // DoKeyDown is called to handle keyDown or autoKey events.
- //
-
- static void DoKeyDown(EventRecord *theEvent)
-
- { char theChar;
-
- theChar = theEvent->message & charCodeMask;
-
- if (theEvent->modifiers & cmdKey) {
- PrepareMenus();
- DoMenuCommand(MenuKey(theChar));
- }
- }
-
-
- //
- // DoActivate is called in response to activate/deactivate events.
- //
-
- static void DoActivate(EventRecord *theEvent)
-
- { WindowPtr theWindow;
- DocumentPtr theDocument;
-
- if ((theWindow = (WindowPtr) theEvent->message) != nil) {
- if ((theDocument = GetDocumentFromWindow(theWindow)) != nil) {
- DoActivateDocument(theDocument, (theEvent->modifiers & activeFlag));
- }
- }
- }
-
-
- //
- // DoUpdate is called in response to update events.
- //
-
- static void DoUpdate(EventRecord *theEvent)
-
- { DocumentPtr theDocument;
-
- if ( ((WindowPtr) theEvent->message) != nil)
- UpdateWindow((WindowPtr) theEvent->message);
- }
-
-
- //
- // DoOSEvent is called in response to Operating System events.
- //
-
- static void DoOSEvent(EventRecord *theEvent)
-
- { DocumentPtr theDocument;
-
- switch ((theEvent->message >> 24) & 0x0FF) {
- case suspendResumeMessage:
- gInBackground = (theEvent->message & resumeFlag) == 0;
- if ((theDocument = GetDocumentFromWindow(FrontWindow())) != nil)
- DoActivateDocument(theDocument, !gInBackground);
- break;
- }
- }
-
-
-
-
- static void DoHighLevelEvent(EventRecord *theEvent)
- {
- AEProcessAppleEvent(theEvent);
- }
-
-
- //
- // Each time WaitNextEvent returns an event to this application, DoEvent
- // is called to handle the event.
- //
-
- static void DoEvent(EventRecord *theEvent)
-
- { WindowPtr theWindow;
- DocumentPtr theDocument;
-
- if ((theWindow = FrontWindow()) != nil) {
- if ((theDocument = GetDocumentFromWindow(theWindow)) != nil) {
- gFrontDocument = theDocument;
- }
- }
-
- switch(theEvent->what) {
- case mouseDown:
- DoMouseDown(theEvent);
- break;
- case mouseUp:
- break;
- case keyDown:
- case autoKey:
- DoKeyDown(theEvent);
- break;
- case activateEvt:
- DoActivate(theEvent);
- break;
- case updateEvt:
- DoUpdate(theEvent);
- break;
- case osEvt:
- DoOSEvent(theEvent);
- break;
- case kHighLevelEvent:
- DoHighLevelEvent(theEvent);
- break;
- }
- }
-
-
- //
- // DoIdle get called repetitively while the application is not doing
- // anything.
- //
-
- static void DoIdleHitTest(void)
-
- {
-
- WindowPtr theWindow;
- DocumentPtr theDocument;
-
- if ((theWindow = FrontWindow()) != nil) {
- if ((theDocument = GetDocumentFromWindow(theWindow)) != nil) {
- SetPort(theDocument->theWindow);
-
- if( theDocument->documentGroup ) {
- Point screenPoint;
- TQ3WindowPointPickData withData;
- unsigned long numPicked;
- TQ3PickObject pickObject;
-
- withData.data.sort = kQ3PickSortNone;
- withData.data.numHitsToReturn= 1;
- withData.data.mask = kQ3PickDetailMaskObject;
-
- GetMouse( &screenPoint );
- withData.point.x = screenPoint.h;
- withData.point.y = screenPoint.v;
-
- withData.vertexTolerance = withData.edgeTolerance = 3;
- // gone and sadly missed in b1c1, delete this line at b2c1!!
- // withData.view = theDocument->theView;
-
- pickObject = Q3WindowPointPick_New(&withData);
-
- Q3View_StartPicking(theDocument->theView, pickObject);
- do {
- Q3DisplayGroup_Submit(theDocument->documentGroup, theDocument->theView);
- } while (Q3View_EndPicking(theDocument->theView) == kQ3ViewStatusRetraverse);
-
- if (Q3Pick_GetNumHits(pickObject, &numPicked) && (numPicked != 0)) {
- SetCursor(*GetCursor(plusCursor));
- } else {
- SetCursor(&qd.arrow);
- }
-
- Q3Object_Dispose(pickObject);
- }
-
- #ifdef _FLASH_HILITE_RGN_
-
- { long dTime;
-
- InvertRgn(theDocument->hiliteRgn);
- Delay(10, &dTime);
- InvertRgn(theDocument->hiliteRgn);
- }
- #endif
-
- }
- }
- }
-
- //
- // DoIdle get called repetitively while the application is not doing
- // anything.
- //
-
- static void DoIdle(void)
-
- {
-
- WindowPtr theWindow;
- DocumentPtr theDocument;
-
- if ((theWindow = FrontWindow()) != nil) {
- if ((theDocument = GetDocumentFromWindow(theWindow)) != nil) {
- Boolean update = false;
-
- SetPort(theDocument->theWindow);
-
- if( theDocument->documentGroup && theDocument->animateLights && theDocument->light) {
- #if defined(ESCHER_VER_15) && ESCHER_VER_15
-
- float angle;
- TQ3GroupPosition lightPosition, position;
- TQ3LightObject theLight;
- TQ3GroupObject lightGroup;
- TQ3Matrix4x4 matrix;
- TQ3Point3D location;
- TQ3Object ellipsoid;
- TQ3Point3D origin;
-
- theDocument->light = kQ3True;
-
- Q3View_GetLightGroup(theDocument->theView, &lightGroup);
- Q3Group_GetFirstPosition(lightGroup, &lightPosition);
-
- /* First one is always on, skip */
- Q3Group_GetNextPosition(lightGroup, &lightPosition);
-
- /* Adjust the transform for the Red sphere */
- Q3RotateTransform_GetAngle(theDocument->lightXform1, &angle);
- angle += 0.8;
- Q3RotateTransform_SetAngle(theDocument->lightXform1, angle);
- Q3Transform_GetMatrix(theDocument->lightXform1, &matrix);
-
- /* Get the Red light */
- Q3Group_GetPositionObject(lightGroup, lightPosition, &theLight);
- /* Get the Red sphere */
- Q3Group_GetFirstPositionOfType(theDocument->light1,
- kQ3ShapeTypeGeometry, &position);
-
- Q3Group_GetPositionObject(theDocument->light1, position, &ellipsoid);
- Q3Ellipsoid_GetOrigin( ellipsoid, &origin);
-
- Q3Point3D_Transform(&origin, &matrix, &location);
- Q3PointLight_SetLocation(theLight, &location);
- Q3Object_Dispose(theLight);
- Q3Object_Dispose(ellipsoid);
-
- /* Adjust the transform for the Green sphere */
- Q3Group_GetNextPosition(lightGroup, &lightPosition);
- Q3RotateTransform_GetAngle(theDocument->lightXform2, &angle);
- angle += 0.5;
- Q3RotateTransform_SetAngle(theDocument->lightXform2, angle);
- Q3Transform_GetMatrix(theDocument->lightXform2, &matrix);
-
- /* Get the Green light */
- Q3Group_GetPositionObject(lightGroup, lightPosition, &theLight);
- /* Get the Green sphere */
- Q3Group_GetFirstPositionOfType(theDocument->light2,
- kQ3ShapeTypeGeometry, &position);
-
- Q3Group_GetPositionObject(theDocument->light2, position, &ellipsoid);
- Q3Ellipsoid_GetOrigin( ellipsoid, &origin);
- Q3Point3D_Transform(&origin, &matrix, &location);
- Q3PointLight_SetLocation(theLight, &location);
- Q3Object_Dispose(theLight);
- Q3Object_Dispose(ellipsoid);
-
- /* Adjust the transform for the Blue sphere */
- Q3Group_GetNextPosition(lightGroup, &lightPosition);
- Q3RotateTransform_GetAngle(theDocument->lightXform3, &angle);
- angle += 0.3;
- Q3RotateTransform_SetAngle(theDocument->lightXform3, angle);
- Q3Transform_GetMatrix(theDocument->lightXform3, &matrix);
-
- /* Get the Blue light */
- Q3Group_GetPositionObject(lightGroup, lightPosition, &theLight);
- /* Get the Blue sphere */
- Q3Group_GetFirstPositionOfType(theDocument->light3,
- kQ3ShapeTypeGeometry, &position);
-
- Q3Group_GetPositionObject(theDocument->light3, position, &ellipsoid);
- Q3Ellipsoid_GetOrigin( ellipsoid, &origin);
- Q3Point3D_Transform(&origin, &matrix, &location);
- Q3PointLight_SetLocation(theLight, &location);
- Q3Object_Dispose(theLight);
- Q3Object_Dispose(ellipsoid);
-
- Q3Object_Dispose(lightGroup);
- update = true;
- #endif
- }
-
- if( theDocument->documentGroup && theDocument->animateModel) {
- TQ3Matrix4x4 tmp;
-
- if( theDocument->rotationDir.x == 0.0 && theDocument->rotationDir.y == 0.0 ) {
- Q3Matrix4x4_SetRotate_XYZ(&tmp, 0.03, 0.08, 0.0);
- Q3Matrix4x4_Multiply(&theDocument->modelRotation, &tmp, &theDocument->modelRotation);
- } else {
- Q3Matrix4x4_SetRotate_XYZ(&tmp, theDocument->rotationDir.x, theDocument->rotationDir.y, 0.0);
- Q3Matrix4x4_Multiply(&theDocument->modelRotation, &tmp, &theDocument->modelRotation);
- }
- update = true;
- }
-
- if( update ) {
- DrawOffscreen(theDocument);
- DrawOnscreen(theDocument);
- DoDrawGrowIcon(theDocument->theWindow);
- }
- }
- }
- }
-
-
- //
- // This is the main event loop of the program. It calls WaitNextEvent
- // and dispatches the returned event until gQuit is true.
- //
-
- void EventLoop(void)
-
- { short gotEvent;
- EventRecord theEvent;
- RgnHandle theMouseRgn;
- Point theLoc;
-
- theMouseRgn = NewRgn();
-
- do {
-
- gotEvent = WaitNextEvent(everyEvent, &theEvent, 0L, theMouseRgn);
- if (gotEvent) {
- DoEvent(&theEvent);
- } else {
- #ifndef PODIUM_APP
- DoIdle();
- #else
- Podium_DoIdle(&theEvent) ;
- #endif
- }
- } while (! gQuit);
-
- DisposeRgn(theMouseRgn);
- }
-